﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace DotNET4Study
{
    public class ReaderWriterLockSlimStudy
    {
        private static List<int> items = new List<int>() { 0, 1, 2, 3, 4, 5 };
        private static ReaderWriterLockSlim rwl = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);

        public static void Excute()
        {
            ////1.使用同一线程写
            //Console.WriteLine("==以下演示同一线程的情形==============");
            //WriterMethod(0);
            //WriterMethod(1);


            ////2.使用多线程写
            //Console.WriteLine("==以下演示2个线程的情形(顺序会有问题)==============");
            //for (int i = 0; i < 2; i++)
            //{
            //    Thread thread = new Thread(WriterMethod);
            //    thread.Start(i);
            //}

            ////3.使用多线程写
            //Console.WriteLine("==以下演示2个线程的情形(顺序OK)==============");
            //for (int i = 0; i < 2; i++)
            //{
            //    Thread thread = new Thread(WriterMethodWithLock);
            //    thread.Start(i);
            //}

            ////4.同一线程读取
            //ReaderMethod(0);
            //ReaderMethod(1);

            ////5.多线程读取(不加锁)
            //for (int i = 0; i < 2; i++)
            //{
            //    Thread thread = new Thread(ReaderMethod);
            //    thread.Start(i);
            //}

            ////6.多线程读取(加锁)
            //for (int i = 0; i < 2; i++)
            //{
            //    Thread thread = new Thread(ReaderMethodWithLock);
            //    thread.Start(i);
            //}

            ////7.多线程读写一体(带写锁)
            //for (int i = 0; i < 2; i++)
            //{
            //    Thread writerThread = new Thread(WriterMethodWithLock);
            //    Thread readerThread = new Thread(ReaderMethod);
            //    writerThread.Start(i);
            //    readerThread.Start(i);
            //}

            ////8.多线程读写一体(带读锁)
            //for (int i = 0; i < 2; i++)
            //{
            //    Thread writerThread = new Thread(WriterMethod);
            //    Thread readerThread = new Thread(ReaderMethodWithLock);
            //    writerThread.Start(i);
            //    readerThread.Start(i);
            //}

            //9.多线程读写一体(带双锁)
            for (int i = 0; i < 2; i++)
            {
                Thread writerThread = new Thread(WriterMethodWithLock);
                Thread readerThread = new Thread(ReaderMethodWithLock);
                writerThread.Start(i);
                readerThread.Start(i);
            }
        }

        private static void WriterMethod(object writer)
        {
            WriterDetail(writer);
        }

        private static void WriterMethodWithLock(object writer)
        {
            rwl.EnterWriteLock();
            WriterDetail(writer);
            rwl.ExitWriteLock();
        }

        private static void WriterDetail(object writer)
        {
            Console.WriteLine("Writer {0} acquired the lock", writer);
            for (int i = 0; i < items.Count; i++)
            {
                items[i]++;
                Console.Write(items[i]);
                Thread.Sleep(10);
            }
            Console.WriteLine("");
            Console.WriteLine("Writer {0} finished", writer);
        }

        static void ReaderMethod(object reader)
        {
            ReadDetail(reader);
        }

        static void ReaderMethodWithLock(object reader)
        {
            rwl.EnterReadLock();
            ReadDetail(reader);
            rwl.ExitReadLock();
        }

        private static void ReadDetail(object reader)
        {
            for (int i = 0; i < items.Count; i++)
            {
                Console.WriteLine("reader {0}, loop: {1}, item: {2}", reader, i, items[i]);
                Thread.Sleep(10);
            }
        }
    }
}